<?php
/**
 * PHP日志类
 * @version 1.0
 * @author Hpyer
 */
class phplog {
	
	/**
	 * 文件指针
	 * @var object
	 */
	private $file;
	
	/**
	 * 用户IP
	 * @var string
	 */
	private $ip;
	
	/**
	 * 配置信息
	 * @param	string	save_dir	日志文件存放路径。默认：'log/'
	 * @param	integer	max_size	日志文件最大尺寸，文件大小超过此值时，文件会被自动打包存档。单位：字节。默认：0(不打包)
	 * @param	string	file_ext	日志文件扩展名。默认：'.log'
	 * @var array
	 */
	private $options = array(
		'save_dir' => 'log/',
		'max_size' => 0,
		'file_ext' => '.log',
	);
	
	/**
	 * 构造函数
	 */
	public function __construct($max_size=0) {
		// 获取IP
		if (!empty($_SERVER['REMOTE_ADDR'])){
			$this->ip = $_SERVER['REMOTE_ADDR'];
		} else {
			$this->ip = '(NO IP)';
		}
		
		// 获取配置
		$options = spExt('phplog');
		if (is_array($options)) foreach ($this->options as $key => $val) {
			if (isset($options[$key])) $this->options[$key] = $options[$key];
		}
		$this->options['save_dir'] = rtrim($this->options['save_dir'], '/') . '/';
		$this->options['max_size'] = abs(intval($this->options['max_size']));
		
		// 获取针对单个文件的最大尺寸限制
		if ($max_size > 0) $this->options['max_size'] = $max_size;
	}

	/**
	 * 记录日志接口
	 * @access	public
	 * @param	string	$filename	文件名（不包含扩展名。支持子目录，如：subdir/mylogfile）
	 * @param	string	$message	信息
	 * @return	void
	 */
	public function log($filename, $message) {
		// 去除消息中的换行、Tab等
		$message = str_replace(array("\r","\n"), array('',' '), $message);
		$this->open_file($filename);
		fwrite(
			$this->file,
			date('Y-m-d') . "\t" . date('H:i:s') . "\t" . $this->ip . "\t" . $message . $this->split()
		);
		fclose($this->file);
	}
	
	/**
	 * 打开日志文件
	 * @access	private
	 * @return	void
	 */
	private function open_file($filename) {
		// 清除文件状态缓存
		clearstatcache();
		
		$the_file = $this->options['save_dir'] . $filename . $this->options['file_ext'];
		$this->mkdirs(dirname($the_file));
		
		// 打开日志文件
		if (file_exists($the_file) ) {
			// 判断日志文件是否超过最大值
			if ($this->options['max_size'] > 0 && filesize($the_file) >= $this->options['max_size']) {
				// 压缩日志文件
				$this->to_gz($filename);
				
				// 删除原日志文件
				unlink($the_file);
				
				$this->file = fopen($the_file, 'w+');
			} else {
				$this->file = fopen($the_file, 'a+');
			}
		} else {
			$this->file = fopen($the_file, 'w+');
		}	
	}	

	/**
	 * 循环建立目录（递归）
	 * @param	string	$dir	目录路径
	 * @param	integer	$mode	目录权限（默认：777）
	 */
	private function mkdirs($dir, $mode = 0777) {
		if (!is_dir($dir)) {
			$this->mkdirs(dirname($dir), $mode);
			return @mkdir($dir, $mode);
		}
		return true;
	}
	
	/**
	 * 根据服务器操作系统类型，返回文件换行符
	 * @access	private
	 * @return	string
	 */
	private function split() {
		return preg_match("/WIN/i", PHP_OS) ? "\r\n" : "\n";
	}
	
	/**
	 * 压缩日志文件
	 * @access	private
	 * @return	void
	 */
	private function to_gz($filename) {
		$file_content = file_get_contents($this->options['save_dir'] . $filename . $this->options['file_ext']);
		$gz_filename = $this->options['save_dir'] . $filename . '-' . date('YmdHis') . $this->options['file_ext'] . '.gz';
		$gz_file_content = gzencode($file_content, 9);
		$gz_file = fopen($gz_filename, 'w+');
		fwrite($gz_file, $gz_file_content);
		fclose($gz_file);
	}
	
}

?>